<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			* {
				padding: 0px;
				margin: 0px;
			}
			
			.box {
				border: 1px solid red;
				width: 540px;
				margin: 30px auto;
				height: 435px;
			}
			
			.box li {
				width: 140px;
				height: 105px;
				list-style: none;
				float: left;
				margin: 20px;
			}
		</style>
	</head>

	<body>
		<div class="box">
			<ul>
				<li style="background:red;"></li>
				<li style="background:blue;"></li>
				<li style="background:yellow;"></li>
				<li style="background:coral;"></li>
				<li style="background:yellow;"></li>
				<li style="background:pink;"></li>
				<li style="background:mediumorchid;"></li>
				<li style="background:black;"></li>
				<li style="background:cadetblue;"></li>
			</ul>
		</div>
		<script type="text/javascript">
			//1.将浮动设置为定位
			var oLi = document.getElementsByTagName('li'); // 通过标签名取到每张图片 
			var zindex = 0; // 定义zindex  是为了得到z-index 图片显示在前
			var arr = []; //存储每一张图片的位置  有两个值offsetleft.top   定义数组二维
			for(var i = 0; i < oLi.length; i++) { //进行遍历li
				oLi[i].style.background = "rgb(" + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + ")"
				arr.push([oLi[i].offsetLeft, oLi[i].offsetTop]) //将对应每张图的li位置存储进二维数组 arr；是为记录位置好改变布局
			}
			console.log(arr)
			for(var i = 0; i < oLi.length; i++) { //再次遍历li
				oLi[i].style.left = arr[i][0] + 'px'; //绝对定位的left值为 arr[i][0]
				oLi[i].style.top = arr[i][1] + 'px'; //绝对定位的top值为 arr[i][1]
				oLi[i].style.position = 'absolute'; //将每个li的定位改为绝对定位
				oLi[i].style.margin = 0; //将margin改为0
			}
			//2
			for(var i = 0; i < oLi.length; i++) { //因是要对所有的li 进行推拽  所以再次遍历li//for 循环让每个li具有拖拽函数
				oLi[i].index = i; ////添加自定义索引  ali[i].index=i;、、、。给每个li 添加index。。。。。。。。。。。。
				duanxian(oLi[i]) //调用拖拽函数 duanxian(ali[i])
			}

			function duanxian(obj) {

				var dx = 0;
				var dy = 0; //	定义x。y初始值0
				obj.onmousedown = function(ev) { //点下li时执行函数
					var ev = ev || window.event; //	兼容
					dx = ev.clientX - obj.offsetLeft; //当前鼠标位置
					dy = ev.clientY - obj.offsetTop; //	得到点下是的x。y off值

					document.onmousemove = function(ev) { //移动时//	        在页面上移动时调用函数
						var ev = ev || window.event; //兼容
						obj.style.zIndex = ++zindex //	改变当前的zIndex （z-index要去杠）=++zindex
						obj.style.left = ev.clientX - dx + 'px'; // ali[i]值得left top随着鼠标变化
						obj.style.top = ev.clientY - dy + 'px'; //移动时的盒子距离
						//					6.给最小路径的元素添加边框。
						for(var i = 0; i < oLi.length; i++) { //		遍历li 
							oLi[i].style.border = "none"; //		清除所有的边框
						}
						var box = duan(obj); //		var box=调用函数ms(obj)  最近的盒子
						box.style.border = "1px solid red"; //		添加样式 border

					}
					document.onmouseup = function() { //	         鼠标抬起时调用函数
						document.onmousemove = null; //	         null化鼠标移动和本身
						document.onmouseup = null;
						//					
						//					7.交换位置。
						var bo = duan(obj); //var minBox=ms(obj);//最近的盒子
						if(bo) { //				判断minbox是否纯在  执行下面	
							bo.style.left = arr[obj.index][0] + 'px'; //	minbox.style.left=arr[obj.index][0]+'px'
							bo.style.top = arr[obj.index][1] + 'px';
							obj.style.left = arr[bo.index][0] + 'px'; //obj			       arr[minbox.index][0]
							obj.style.top = arr[bo.index][1] + 'px';
							var tam = obj.index; //					var temp=obj.index;
							obj.index = bo.index; //					obj.index=minBox.index;
							bo.index = tam; //							minBox.index=temp;
							bo.style.border = "none"; //				 	最近的盒子的边框设置为none；
						} else { //				否则	obj   =arr[obj....]	    回到原位        
							obj.style.left = arr[obj.index][0] + 'px';
							obj.style.top = arr[obj.index][1] + 'px';

						}

					}
					return false; //	当鼠标点下所对应li调用函数  记得return false；
				}
			}

			//			3.盒子碰撞。
			function peng(obj1, obj2) { //函数封装  peng(obj,obj1) //	判断！（left+width<left1 ||left>left1+width1 ）不是
				if(!(obj1.offsetLefteft > obj2.offsetLeft + obj2.offsetWidth || obj1.offsetLefteft < obj2.offsetLeft + obj2.offsetWidth || obj1.offsetTop > obj2.offsetTop + obj2.offsetTop || obj1.offsetTo < obj2.offsetTop + obj2.offsetTop)) {
					return true; //		return true
				} else {
					return false; //		否则返回false
				}
			}

			//          4.勾股定理求最短距离o
			function gg(obj1, obj2) { //函数封装  gg(obj,obj1)
				var a = obj1.offsetLeft - obj2.offsetLeft; //	求两点之间距离 a=offl-off1l  b=offt-off1
				var b = obj1.offsetTop - obj2.offsetTop;
				return Math.sqrt(a * a + b * b); //	返回   math。sqrt（a*a+b*b）  求斜线
			}
			//			5.判断求出最小路径的图片。-->
			function duan(obj) { //函数封装 ms（obj）
				var dindex = -1; //定义  假设一个最小索引
				var dvalue = 500; // 定义   假设一个最小值  （1000）
				for(var i = 0; i < oLi.length; i++) { //for遍历ali
					if(peng(obj, oLi[i]) && obj != oLi[i]) {
						//判断前提是否碰上Math.floor(Math.random()*256)peng(obj,ali[i]) &&!=ali[i]//同时满足碰上的不包括自己；
						var wcao = gg(obj, oLi[i]); //wcao等于得失最短距离       得到每个数的距离  var jl=gg（obj，ali[i]）;//
						if(wcao < dvalue) { // //      判断如果得到的距离比最小值还小    
							dvalue = wcao; ////      最小值换人
							dindex = i; //       最小索引=i
						}
					}
				}
				if(dindex != -1) { //if如果最小索引不等于-1	
					return oLi[dindex] //  返回最下的li对象 ali[那个最小索引]
				} else {
					return false; //  else 返回false
				}

			}
		</script>
	</body>

</html>
<!--1.将浮动布局改成定位布局
2.拖拽

6.给最小路径的元素添加边框。
7.交换位置。

3.盒子碰撞。
4.封装勾股定理求最短的距离。
5.判断求出最小路径的图片。-->